package org.dubnation.car.service.impl;

import org.apache.ibatis.annotations.Options;
import org.dubnation.auth.context.LoginContext;
import org.dubnation.base.constants.SystemConstants;
import org.dubnation.base.enums.ResponseCode;
import org.dubnation.base.exception.BusinessException;
//import org.dubnation.base.util.TextTransUtil;
import org.dubnation.base.util.cart.CartInfo;
import org.dubnation.base.util.cart.CartVO;
import org.dubnation.base.util.audit.DubnationAssert;
import org.dubnation.base.util.cart.CheckedItem;
import org.dubnation.car.domain.Car;
import org.dubnation.car.domain.CarCart;
import org.dubnation.car.domain.CarOnlineShop;
import org.dubnation.car.mapper.CarCartMapper;
import org.dubnation.car.mapper.CarMapper;
import org.dubnation.car.mapper.CarOnlineShopMapper;
import org.dubnation.car.service.ICarCartService;
import org.dubnation.base.service.impl.BaseServiceImpl;
import org.dubnation.org.domain.Employee;
import org.dubnation.org.mapper.EmployeeMapper;
import org.dubnation.user.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zhu
 * @since 2023-11-28
 */
@Service
@Transactional
public class CarCartServiceImpl extends BaseServiceImpl<CarCart> implements ICarCartService {

    @Autowired(required = false)
    private CarMapper carMapper;

    @Autowired(required = false)
    private CarCartMapper carCartMapper;

    @Autowired
    private CarCart carCart;

    @Autowired(required = false)
    private CarOnlineShopMapper carOnlineShopMapper;

    @Autowired
    private CarOnlineShop onlineShop;

    @Autowired
    private CartVO cartVO;

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @Autowired(required = false)
    private EmployeeMapper employeeMapper;

    /**
     * 根据车辆id新增购物车
     * @param carId
     */
    @Override
    public void insertByCarId(Long carId) {
        List<CarCart> dataBaseCarCarts = carCartMapper.queryAll();
        Car car = carMapper.queryById(carId);
        String shopName = String.format("%s官方旗舰店", car.getBrand());
        DubnationAssert.isNotNull(car, ResponseCode.RESPONSE_CODE_400);
        //若此商品购物车中已存在则只需修改该商品数量即可
        Boolean foundCart = false;
        for (CarCart dataBaseCarCart : dataBaseCarCarts) {
            if (carId.equals(dataBaseCarCart.getCar().getId())){  //TODO ==只能比较基本数据类型, 包装类是引用数据类型
                Integer num = dataBaseCarCart.getCount() + 1;
                dataBaseCarCart.setCount(num); //商品数量+1
                dataBaseCarCart.setUpdateTime(new Date());
                carCartMapper.update(dataBaseCarCart);
                foundCart = true;
                break;
            }
        }
        //购物车数据库中没有当前新增商品
        if (foundCart == false){
            //获取车辆的id, brand, title, carType-name, costPrice
            //给购物车对应字段设置值
            //给网店新增数据
            Boolean foundShop = false;
            List<CarOnlineShop> carOnlineShops = (List<CarOnlineShop>) redisTemplate.opsForValue().get(SystemConstants.CART_TREE_SHOP);
            if (Objects.isNull(carOnlineShops)){
                carOnlineShops = carOnlineShopMapper.queryAll();
                redisTemplate.opsForValue().set(SystemConstants.CART_TREE_SHOP, carOnlineShops);
            }
            for (CarOnlineShop carOnlineShop : carOnlineShops) {
                //保证网店数据库表中的店铺不重复
                if (carOnlineShop.getShopName().equals(shopName)){
                    foundShop = true;
                    break;
                }
            }
            //网店数据库中没有该数据
            if (foundShop == false){
                redisTemplate.delete(SystemConstants.CART_TREE_SHOP);
                onlineShop.setShopName(shopName);
                onlineShop.setSellerId(car.getSellerId());
                Integer selectedNum = 0;
                Integer thisSellNum = 0;
                if (dataBaseCarCarts != null && dataBaseCarCarts.size() > 0){
                    for (CarCart dataBaseCarCart : dataBaseCarCarts) {
                        //若该店铺所有商品处于选中状态, 则店铺应选中
                        if (car.getSellerId() == dataBaseCarCart.getSeller().getId()){
                            thisSellNum++;
                            if (!SystemConstants.CarCart.SELECTED.equals(dataBaseCarCart.getStatus())){
                                //有商品没有被选中
                                selectedNum++;
                            }
                        }
                    }
                }
                if (selectedNum == 0 || (thisSellNum - selectedNum) == 1){
                    //店铺设置为选中状态
                    onlineShop.setStatus(SystemConstants.CarOnlineShop.SELECTED);
                }
                carOnlineShopMapper.insert(onlineShop);
                redisTemplate.delete(SystemConstants.CART_TREE_SHOP); //延时双删
            }
            carCart.setShop(onlineShop);
            carCart.setUnitPrice(car.getCostPrice());
            carCart.setCount(1);
            carCart.setCar(car);
            Employee employee = employeeMapper.queryById(car.getSellerId());
            carCart.setSeller(employee);
            carCart.setCreatTime(new Date());
            //商品新增即选中
            carCart.setStatus(SystemConstants.CarCart.SELECTED);
            Object loginAdmin = LoginContext.getLoginAdmin();
            if (loginAdmin instanceof User){
                carCart.setUser((User) loginAdmin);
                //新增购物车
                carCartMapper.insert(carCart);
            }
        }
    }

    /**
     * 重写修改方法
     * @param carCart
     */
    @Override
    public void update(CarCart carCart) {
        Integer num = null;
        if ("SUBTRACT".equals(carCart.getChangeType())){
            //商品数量count减1, 商品总价totalPrice*count
            num = carCart.getCount() - 1;
        }else if ("ADD".equals(carCart.getChangeType())){
            //商品数量count加1, 商品总价totalPrice*count
            num = carCart.getCount() + 1;
        }else throw new BusinessException(ResponseCode.RESPONSE_CODE_400);
        carCart.setCount(num);
        super.update(carCart);
    }

    /**
     * 清空购物车
     */
    @Override
    @Transactional
    public void clearCart() {
        carCartMapper.clearCart();
        carCartMapper.deleteAllOnlineShop();
        redisTemplate.delete(SystemConstants.CART_TREE_SHOP);
    }

    /**
     * 获取购物车数据以shopName分组返回前端
     * @return
     */
    @Override
    public CartVO getCarCartByShopName() {
        List<CartInfo<CarCart>> cartInfos = new ArrayList<>();
        //1.获取购物车中所有商品的店铺名
        List<CarOnlineShop> carOnlineShops = (List<CarOnlineShop>) redisTemplate.opsForValue().get(SystemConstants.CART_TREE_SHOP);
        if (Objects.isNull(carOnlineShops)){
            carOnlineShops = carOnlineShopMapper.queryAll();
            redisTemplate.opsForValue().set(SystemConstants.CART_TREE_SHOP, carOnlineShops, 72, TimeUnit.HOURS);
        }
        //2.根据店铺名获取对应的商品数据
        if (carOnlineShops.size() != 0){
            carOnlineShops.forEach(carOnlineShop -> {
                CartInfo<CarCart> cartInfo = new CartInfo<>();
                List<CarCart> carCartList = carCartMapper.queryByShopId(carOnlineShop.getId());
                //3.将店铺名和对应商品储存到集合中
                cartInfo.setShopName(carOnlineShop.getShopName());
                cartInfo.setT(carCartList);
                cartInfos.add(cartInfo);
            });
            Integer totalCommodity = 0;
            //获取数据的总条数
            for (CartInfo<CarCart> cartInfo : cartInfos) {
                List<CarCart> carCarts = cartInfo.getT();
                totalCommodity = totalCommodity + carCarts.size();
            }
            cartVO.setCartInfos(cartInfos);
            cartVO.setTotal(totalCommodity);
        }
        return cartVO;
    }

    /**
     * 重写删除方法
     * @param id
     */
    @Override
    public void delete(Serializable id) {
        CarCart carCart = carCartMapper.queryById(id);
        List<CarCart> carCarts = carCartMapper.queryByShopId(carCart.getShop().getId());
        super.delete(id);
        //如果购物车中没有相应的网店商品数据, 则将网店数据库表中对应的店铺删除
        if (carCarts.size() == 1){
            //更新缓存
            redisTemplate.delete(SystemConstants.CART_TREE_SHOP);
            carOnlineShopMapper.delete(carCart.getShop().getId());
            redisTemplate.delete(SystemConstants.CART_TREE_SHOP);
        }
    }
}
